package com.zz.framework.core.base

import android.content.Context
import android.os.Build
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import com.zz.framework.core.annotation.BindViewModel
import com.zz.framework.core.common.ViewModelFactory
import com.zz.framework.core.ext.showToast
import java.lang.reflect.Field

/**
 * Copyright © 2020 zanezhao All rights reserved.
 * Created on 2020/3/19 5:38 PM.
 * @version: V1.0
 */
open class BaseViewModelDialogFragment : DialogFragment(), LifecycleObserver {
    private lateinit var viewModel: BaseViewModel<*>

    override fun onAttach(context: Context) {
        super.onAttach(context)
        //默认注册ViewModel
        initViewModel()
    }

    /**
     *  根据 @BindViewModel 注解, 查找注解标示的变量（ViewModel）
     *  并且 创建 ViewModel 实例, 注入到变量中
     */
    private fun initViewModel() {
        javaClass.fields
            .filter { it.isAnnotationPresent(BindViewModel::class.java) }
            .forEach {
                it?.apply {
                    isAccessible = true
                    var annotation = this.getAnnotation(BindViewModel::class.java)
                    set(
                        this@BaseViewModelDialogFragment,
                        getViewModel(annotation.isSingle, annotation.isRegisterError, this)
                    )
                }
            }

    }

    private fun getViewModel(isSingle: Boolean, isRegisterError: Boolean, field: Field): ViewModel {
        var viewModelName: String? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            field.genericType.typeName
        } else {
            null
        }
        if (viewModelName == null) {
            viewModelName = this.javaClass.getCanonicalName()
        }
        if (isSingle) viewModelName =
            "${this.javaClass.canonicalName}${this.toString()}:$viewModelName" else viewModelName
        val mViewModel: BaseViewModel<*> =
            ViewModelFactory.createViewModel(this, viewModelName, field,isSingle)
        if (isRegisterError) {
            observeErrorLiveData(mViewModel)
        }
        observeFinishLiveData(mViewModel)
        viewModel = mViewModel
        return mViewModel
    }

    protected fun observeErrorLiveData(viewModel: BaseViewModel<*>) {
        viewModel?.errorLiveData?.observe(
            this,
            Observer { it?.let { error(it.code, it.message) } })
    }

    protected fun observeFinishLiveData(viewModel: BaseViewModel<*>) {
        viewModel?.finishedLiveData?.observe(
            this,
            Observer { it?.let {
                dismissProgress()
            }})
    }

    override fun onDestroyView() {
        removeViewModelObserver()
        super.onDestroyView()
    }

    private fun removeViewModelObserver() {
        if (this::viewModel.isInitialized) {
            viewModel?.let {
                lifecycle.removeObserver(it)
            }
        }
    }

    fun showProgress() {
        getBaseActivity()?.showProgress()
    }

    fun dismissProgress() {
        getBaseActivity()?.dismissProgress()
    }

    fun getBaseActivity(): BaseUIActivity? {
        if (activity is BaseUIActivity) {
            return activity as BaseUIActivity
        } else {
            return null
        }
    }

    open fun error(code: Int, message: String) {
        dismissProgress()
        error(message)
    }

    open fun error(message: String) {
        activity?.showToast(message)
    }

    override fun onDestroy() {
        super.onDestroy()
        dialog?.dismiss()
    }

    open fun show(activity: FragmentActivity) {
        show(requireActivity().supportFragmentManager, tag)
    }
}